package com.infosys.newSimpleInvertedIndex.engine;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedDeque;

import com.google.common.collect.Lists;

import com.infosys.newSimpleInvertedIndex.models.DocumentModel;
import com.infosys.newSimpleInvertedIndex.models.ParsedDoc;

public class IndexFactory {
    // LESSON: avoid creation of instance
    private IndexFactory(){
        
    }

    public static List<ParsedDoc> makeParsedDocumentsParallel(List<DocumentModel> documentModels){
        int logicalThreads = Math.max(Runtime.getRuntime().availableProcessors(), 1);
        final Collection<ParsedDoc> parsedDocs = new ConcurrentLinkedDeque<>();
        List<Thread> threads = new ArrayList<>();
        DocumentParser parser = new DocumentParser();
        for (final List<DocumentModel> partition : Lists.partition(documentModels, logicalThreads)){
            Thread thread = new Thread(() -> {
                parsedDocs.addAll(makeParsedDocuments(partition, parser));
            });

            threads.add(thread);
            thread.start();
        }
        for (Thread thread : threads){
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        List<ParsedDoc> parsedDocList = new ArrayList<>(parsedDocs);
        return parsedDocList;
    }

    public static List<ParsedDoc> makeParsedDocuments(List<DocumentModel> documentModels, DocumentParser parser){
        List<ParsedDoc> parsedDocs = new ArrayList<>();
        for (DocumentModel documentModel : documentModels){
            parsedDocs.add(parser.parseDocument(documentModel));
        }
        return parsedDocs;
    }

}
